/*
 * 软件著作权：中国农业银行软件开发中心
 *
 * 系统名称：Plantix-Console
 * 
 */
package com.autoscript.ui.helper;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;





/**
 * 字符串工具
 * @author 龙色波
 *
 */
public class StringHelper {
	static final String keywords[] = {
        "abstract", "double", "int", "strictfp", "boolean", "else", "interface", "super", "break", "extends", 
        "long", "switch", "byte", "final", "native", "synchronized", "case", "finally", "new", "this", 
        "catch", "float", "package", "throw", "char", "for", "private", "throws", "class", "goto", 
        "protected", "transient", "const", "if", "public", "try", "continue", "implements", "return", "void", 
        "default", "import", "short", "volatile", "do", "instanceof", "static", "while", "true", "false", 
        "null"
    };	
	
	
    /**
     * 在指定的字符串,正向搜索指定字符串任一字符出现位置,只要找到其中一个字符就返回,没有找到时,返回-1
     * @param startpos strMonther 开始位置
     * @param strMonther 被搜索的串
     * @param strChild 
     * @return
     */
    public static int findInStr(int startpos,String strMonther,String strChild){
        for(int i=startpos;i<strMonther.length();i++){
            if(strChild.indexOf(strMonther.charAt(i))>=0)
                return i;
        }
        return -1;
    }
    /**
     * 判断字符串是否为数字
     * @param str
     * @return
     */
    public static boolean isNumber(String str){
        int beginindex;
        
        if(str==null || str.length()==0)
            return false;
        String strTest = str.trim();
        if(strTest.length()==0)
            return false;
        //带符号,则跳过
        if(strTest.charAt(0)=='-'||strTest.charAt(0)=='+')
            beginindex =1;
        else
            beginindex = 0;
        for(int i=beginindex;i<str.length();i++){
            if(str.charAt(i)=='.'||str.charAt(i)=='%')
                continue;
            else    if(str.charAt(i)>='0' && str.charAt(i)<='9')
                continue;
            else
                return false;
        }
        //只有符号不是数字
        if(beginindex==1 && str.length()<2)
            return false;
        else
            return true;
    }
    /**
     * 判断字符串是否为数字
     * @param str
     * @return
     */
    public static boolean isNumber(char ch){
    	if(ch>='0' && ch<='9')
    		return true;
    	else
    		return false;
    }
    /**
     * 判断字符是否为字母
     * @param ch 测试字符
     * @return boolean 为字母是返回true;否则返回false
     */
    public static boolean isLetter(char ch){
        if((ch>='a' && ch<='z')||(ch>='A' && ch<='Z'))
                return true;
        else
            return false;
    }
    /**
     * 判断字符串是否为字母
     * @param str 测试字符串
     * @return boolean 为字母是返回true;否则返回false
     */
    public static boolean isLetter(String str){
    	if(isEmpty(str)){
    		return false;
    	}
        for(int i=0;i<str.length();i++){
        	if(!isLetter(str.charAt(i)))
        		return false;
        }
        return true;
    }    
    /**
     * 在指定的字符串,反向搜索指定字符串任一字符出现位置,只要找到其中一个字符就返回,没有找到时,返回-1
     * @param startpos strMonther 开始位置
     * @param strMonther 被搜索的串
     * @param strChild 
     * @return
     */    
    public static int reversalFindInStr(int startpos,String strMonther,String strChild){
        for(int i=startpos;i>=0;i--){
            if(strChild.indexOf(strMonther.charAt(i))>=0)
                return i;
        }
        return -1;        
    }
    /**
     * 查询strFind在strMonther出现的次数
     * @param strMonther 母串
     * @param strFind 搜索串
     * @return int 匹配次数
     */
    public static int findStrNum(String strMonther,String strFind){
        int startpos,endpos;
        int sum=0;
        endpos = 0;
        startpos = 0;
        while(endpos>=0){
            endpos = strMonther.indexOf(strFind,startpos);
            if(endpos!=-1){
                sum++;
                startpos = endpos+1;
            }
        }
        return sum;
    }
    /**
     * 转换用指定字符分隔的字符串为字符串 
     * @param s 需要转换的字符串
     * @param ch 分割字符
     * @return String[] 分隔后的字符串
     * @remark 使用String.split方法时,当参数为'.'不能正常转换
     */
    public static String [] split(String s,char ch){
    	  return splitString(s,String.valueOf(ch));
    }
    /**
     * 判断字符串是否拆分
     * @param str 字符串
     * @param separator 分隔符
     * @return boolean 是拆分返回true;否则返回false
     */
    public static boolean isSplit(String str,String separator){
        if (splitString(str, separator).length > 1)
            return true;
        else
            return false;
    }
    
    /**
     * 拆分字符串，将用一定符号分割的字符串拆分为一个数组
     * @param str 要进行拆分的字符串
     * @param separator 分隔符
     * @return 拆分后的数组
     * @remark 不能使用str.spilt.拆分1,2,3,,,,有问题
     */
    public static String[] splitString(String str, String separator) {
       StringBuffer buff = new StringBuffer();
       buff.append(str);
       return splitString(buff,separator);
    }   
    /**
     * 判断字符串是否为重复字符串格式,例如A:4代表四个字符A
     * @param str 检测串
     * @param repeat 重复指示串
     * @return boolean 是重复格式时,返回true;否则返回false
     */
    public static boolean isRepeat(String str,String repeat){
        if(str==null) return false;
        int pos;
        pos = str.indexOf(repeat);
        //没有找到或者最后一个字符或者第一个
        if(pos==-1||pos == str.length()-1||pos == 0) return false;
        //下一个字符必须为数字
        if(!isNumber(String.valueOf(str.charAt(pos+1))))
            return false;
        else
            return true;
    }
    
    /**
     * 在指定的字符串,正向搜索指定字符串数组任一字符串出现位置,只要找到其中一个字符串就返回,没有找到时,返回-1
     * @param startpos strMonther 开始位置
     * @param strMonthers 被搜索的字符串
     * @param strChilds 搜索字符串数组
     * @param isIgnoreCase 是否忽略大小写
     * @return List 返回找到位置和对应strChilds索引,List第一个元素为找到位置,第二个元素为strChilds索引
     */
    public static List<Integer> findInStrArray(int startpos,String strMonther,String strChilds[],boolean isIgnoreCase){
        int pos;
        int minPos,minIndex ;
        int keyLen;
        char ch;
        //初始化位置
        minPos = strMonther.length();
        minIndex = strChilds.length ;
        List<Integer> retVal = new ArrayList<Integer>();
        for(int j=0;j<strChilds.length;j++){
           if(!isIgnoreCase){
        	   pos = strMonther.indexOf(strChilds[j],startpos);
           }else{
                pos = indexOfIgnoreCase(strMonther,strChilds[j],startpos);
           }
           
           if(pos >= 0){
        	   keyLen = strChilds[j].length();
              	//如果strChilds[j]本身不是一个单词,就不用检查
              	if(isWord(strChilds[j])){
   		            //检查strChilds[j]前后第一字符是否为数字,字母,_,如果不是则认为是一个单词
   		            if(pos-1>=0){
   		            	ch = strMonther.charAt(pos -1);
   		            	if(StringHelper.isNumber(ch)||StringHelper.isLetter(ch)||ch == '_'){
   		            		continue;
   		            	}
   		            }
   		            if(pos !=-1 && pos+keyLen<strMonther.length()){
   		            	ch = strMonther.charAt(pos+keyLen);
   		            	if(StringHelper.isNumber(ch)||StringHelper.isLetter(ch)||ch == '_'){
   		            		continue;
   		            	}            	
   		            }
              	}        	   
             //取首先找到的位置
              if(pos<minPos){
                  minPos = pos;
                  minIndex = j;
              }
           }
        }
        if(minPos == strMonther.length()){
            retVal.add(new Integer(-1));
            retVal.add(new Integer(-1));
        }else{
            retVal.add(new Integer(minPos));
            retVal.add(new Integer(minIndex));
        }
        return retVal;
    }   
    /**
     * 忽略大小写查找
     * @param strMonther 母串
	 * @param string 字符串
	 * @param startpos 开始
	 * @return int 返回查找位置
	 */
	public static int indexOfIgnoreCase(String strMonther,String string, int startpos) {
		return strMonther.toLowerCase().indexOf(string.toLowerCase(), startpos);
		
	}
	/**
     * 字符串忽略大小写全部替换
     * @param strMonther 原字符串
     * @param strOld 被替换的字符串
     * @param strNew 替换新串
     * @return String 返回替换后的字符串
     */
    public static String replaceAllIgnoreCase(String strMonther,String strOld,String strNew){
        StringBuffer strReturn = new StringBuffer();
        String strLowerCase,strLowerCaseFind;
        int spos,epos;
        int len;
        if(strMonther == null )
            return null;
        strLowerCase = strMonther.toLowerCase();
        strLowerCaseFind = strOld.toLowerCase();
        spos = epos = 0;
        len = strOld.length();
        while(epos>=0){
            epos = strLowerCase.indexOf(strLowerCaseFind,spos);
            if(epos>=0){
                //连接字符串
                strReturn.append(strMonther.substring(spos,epos)).append(strNew);
                //移动位置
                spos = epos + len;
            }else{
                strReturn.append(strMonther.substring(spos));
            }
        }
        return strReturn.toString();
    }
    /**
     * 截断字符串空格
     * @return String
     */
    public static String trim(String str){
        if(str!=null)
            return str.trim();
        else
            return str;
    }
    /**
     * 判断字符串是否为空串或null
     * @param str 
     * @return boolean
     */
    public static boolean isBlank(String str){
    	return StringUtils.isBlank(str);
    }

    /**
     * 使用StringBuffer替换字符串
     * @param buffer 母串
     * @param oldStr 被替换的旧串
     * @param newStr 需要替换的新串
     * @return 
     */
    public static StringBuffer replaceAll(StringBuffer buffer,String oldStr,String newStr){
    	int epos,spos;
    	int len,nlen;
    	
    	if(buffer == null||oldStr == null||newStr == null)
    		return null;
    	epos = spos = 0;
    	len = oldStr.length();
    	nlen = newStr.length();
    	StringBuffer newBuffer = new StringBuffer();
    	newBuffer.append(buffer);
    	while(epos>=0){
    		epos = newBuffer.indexOf(oldStr, spos);
    		if(epos>=0){
    			buffer = newBuffer.replace(epos, epos+len, newStr);
    			spos = epos+nlen;
    		}
    		
    	}
    	return newBuffer;
    }
    /**
     * 拆分字符串，将用一定符号分割的字符串拆分为一个数组
     * @param str 要进行拆分的字符串
     * @param separator 分隔符
     * @return 拆分后的数组
     * @remark 不能使用str.spilt.拆分1,2,3,,,,有问题
     */
    public static String[] splitString(StringBuffer str, String separator) {
        List<String> list = new ArrayList<String>();
        String strtemp;
        int spos,epos;
        int len;
        
        epos = 0;
        spos = 0;
        len = separator.length();
        while(epos>=0){
            epos = str.indexOf(separator,spos);
            if(epos == -1){
             strtemp = str.substring(spos+len -1);
             if(strtemp!=null )
             list.add(strtemp);
            }else {
             strtemp = str.substring(spos+len -1, epos);
             if(strtemp!=null)
              list.add(strtemp);
            }
            
            //移动开始位置
            spos = epos+len;
        }
        return (String[])list.toArray(new String[list.size()]);
    }
    /**
     * 使用StringBuffer替换字符串
     * @param buffer 母串
     * @param oldStr 被替换的旧串
     * @param newStr 需要替换的新串
     * @return 
     */
    public static StringBuffer replaceAll(String str,String oldStr,String newStr){
    	StringBuffer buff = new StringBuffer();
    	
    	buff.append(str);
    	return replaceAll(buff,oldStr,newStr);
    }
    /**
     * 转换成小写
     * @param ch 字符
     * @return 小写字符
     */
    public static char toLower(char ch){
    	
    	if(ch>='a' && ch<='z')
    		return ch;
    	else if(ch>='A' && ch<='Z')
    		return (char)((int)ch - (int)'A'+(int)'a');
    	else
    		return ch;
    }
    /**
     * 转换成大写
     * @param ch 字符
     * @return 大写字符
     */
    public static char toUpper(char ch){
    	
    	if(ch>='A' && ch<='Z')
    		return ch;
    	else if(ch>='a' && ch<='z')
    		return (char)((int)ch - (int)'a'+(int)'A');
    	else
    		return ch;
    }   
    /**
     * 第一个字母变大写
     * @param str 字符串
     * @return 转换后字符串
     */
    public static String toFirstUpper(String str){
    	if(str!=null){
	    	if(str.length()>1){
		    	String strFirst = str.substring(0, 1).toUpperCase();
		    	return strFirst + str.substring(1);
	    	}else if(str.length()==1){
	    		return str.substring(0, 1).toUpperCase();
	    	}else
	    		return str;
    	}else
    		return str;
    	
    }
    /**
     * 第一个字母变小写
     * @param str 字符串
     * @return 转换后字符串
     */
    public static String toFirstLower(String str){
    	if(str!=null){
	    	if(str.length()>1){
		    	String strFirst = str.substring(0, 1).toLowerCase();
		    	return strFirst + str.substring(1);
	    	}else if(str.length()==1){
	    		return str.substring(0, 1).toLowerCase();
	    	}else
	    		return str;
    	}else
    		return str;
    }
    /**
     * 获取最末级字符串 例如a.b.c 返回c
     * @param str 需要处理str
     * @param separator 级间分隔符
     * @return
     */
    public static String getLastLevelString(String str,String separator){
    	if(str == null )
    		return null;
    	if(str.length()==0)
    		return str;
    	int pos;
    	pos = str.lastIndexOf(separator);
    	if(pos>=0){
    		return str.substring(pos+1);
    	}else
    		return str;
    }
    /**
     * 获取当前中文格式的年月日串 格式:YYYY-MM-DD
     * @return 中文格式的年月日串
     */
    public static String getCNYearMonthDay(){
    	java.text.SimpleDateFormat   fm=new   java.text.SimpleDateFormat("yyyy-MM-dd");
    	java.util.Date date;
    	date = new Date(System.currentTimeMillis());
    	return fm.format(date);
    }
    /**
     * 判断str 是否以value结束,value忽略大小写
     * @param str 
     * @param value
     * @return
     */
    public static boolean endsWithIgnoreCase(String str,String value){
    	return str.toLowerCase().endsWith(value.toLowerCase());
    }
    /**
     * 忽略大小写,替换最后一次出现的字符串
     * @param strMonther 母串
     * @param strOld 旧串
     * @param strNew 新串
     */
    public static String replaceLastStringIgnoreCase(String strMonther,String strOld,String strNew ){
    	StringBuffer strReturn = new StringBuffer();
        String strLowerCase,strLowerCaseFind;
        int spos,epos;
        int len;
        if(strMonther == null )
            return null;
        strLowerCase = strMonther.toLowerCase();
        strLowerCaseFind = strOld.toLowerCase();
        spos = epos = 0;
        len = strOld.length();
        epos = strLowerCase.lastIndexOf(strLowerCaseFind);
        if(epos<0){
        	return strMonther;
        }
        strReturn.append(strMonther.substring(spos,epos)).append(strNew).append(strMonther.substring(epos+len));
        
        return strReturn.toString(); 
    }
	/**
	 * 校验中文字符串合法性
	 * @param name
	 * @return
	 */
	public static boolean validateChineseString(String name){
	    if(isBlank(name))
	        return false;
	    boolean result = true;
	    char chs[] = name.toCharArray();
	    if(!Character.isUnicodeIdentifierStart(chs[0])){
	        result = false;
	    } else {
	        for(int i = 1; i < chs.length; i++){
	            if(Character.isUnicodeIdentifierPart(chs[i]))
	                continue;
	            result = false;
	            break;
	        }
	    }
	    return result;
	}
	/**
	 * 校验英文字符串合法性
	 * @param name
	 * @return
	 */
	public static boolean validateEnglishString(String name){
	    if(isBlank(name))
	        return false;
	    boolean result = true;
	    char chs[] = name.toCharArray();
	    if(!Character.isJavaIdentifierStart(chs[0])){
	        result = false;
	    } else {
	        for(int i = 1; i < chs.length; i++){
	            if(Character.isJavaIdentifierPart(chs[i]))
	                continue;
	            result = false;
	            break;
	        }
	    }
	    if(result){
	        for(int i = 0; i < keywords.length; i++){
	            if(!keywords[i].equalsIgnoreCase(name))
	                continue;
	            result = false;
	            break;
	        }
	
	    }
	    if(result){
	        for(int i = 0; i < chs.length; i++){
	            if(chs[i] <= '\200')
	                continue;
	            result = false;
	            break;
	        }
	    }
	    return result;
	}
	
	/**
	 * 截去首次出现分隔符之前的字符串，如果分隔符正好在字符串的第一个字母，则一并截去
	 * @return
	 */
	public static String trimFirstDiv(String str, String div){
		int pos;
	    pos = str.indexOf(div);
	    if(pos>0){
	    	return str.substring(pos + div.length());
	    }else if(pos ==0){
	    	String tmp = str.substring(1);
	    	if(tmp.contains(div)){
	    		return tmp.substring(tmp.indexOf(div)+1);
	    	}else{
	    		return tmp.trim();
	    	}
	    }
	    return null;
		
	}
	/**
	 * 判断字符串是否为空串或者null
	 * @param val 
	 * @return 空或者null返回true;否则返回false
	 */
	public static boolean isEmpty(String val){
		 if(val!=null)
			 val = val.trim();
		return StringUtils.isEmpty(val);
	}
	
	
	/**
	 * 通过strChilds指定分隔串数组,拆分strMonther
	 * @param strMonther 被拆分的字符串
	 * @param strChilds 分隔串数组
	 * @param isIgnoreCase 是否忽略大小写
	 * @return 返回字符串数组
	 */
	public static String[] splitByStrArray(String strMonther,String strChilds[],boolean isIgnoreCase){
	    int startpos, endpos;
        String strTemp;
        int keyLen;
        int childIndex;
        
        startpos = 0;
        List<String> items = new ArrayList<String>();
        List<Integer> retList;
        	                
        while (startpos <= strMonther.length() - 1) {
            retList = findInStrArray(startpos, strMonther, strChilds,isIgnoreCase);
            endpos = retList.get(0).intValue();
            childIndex = retList.get(1).intValue();
            // 搜索结束
            if (endpos == -1) {
                strTemp = strMonther.substring(startpos);
            } else {
                strTemp = strMonther.substring(startpos, endpos);
            }
            
            strTemp = strTemp.trim();
            if (strTemp.length() > 0) {
                //不存在,则加入
                if (items.indexOf(strTemp) == -1)
                    items.add(strTemp);                    
            }
            // 移动位置
            if (endpos != -1){
            	//跳过strChilds指定的key            	
            	keyLen = strChilds[childIndex].length();
                startpos = endpos + keyLen;
            }else
                break;
        }
        return (String[]) items.toArray(new String[items.size()]);
	}
	/**
	 * 判断字符串是否为一个单词
	 * @param val 测试串
	 * @return 
	 */
	private static boolean isWord(String val) {
		if(isEmpty(val)){
			return false;
		}
		char ch;
		for(int i=0;i<val.length();i++){
			ch = val.charAt(i);
			//为字母,数字,空格,tab,_?
			if(!isLetter(ch)&&!isNumber(ch)&&ch != ' '&&ch !='\t'&&ch!='_'){
				return false;
			}
		}
		return true;
	}
	/**
	 * 把在strMonther 中出现的strChilds替换为strNew
	 * @param strMonther 原串 
	 * @param strChilds 查找串数组
	 * @param strNew 新串
	 * @param isIgnoreCase 是否忽略大小写
	 */
	public static String replaceAllInStrArray(String strMonther,String strChilds[],String strNew,boolean isIgnoreCase){
		String retStr;
		
		retStr = strMonther;
		for(int i=0;i<strChilds.length;i++){
			if(isIgnoreCase){
				retStr = replaceAllIgnoreCase(retStr, strChilds[i], strNew);
			}else{
				retStr = replaceAll(retStr,strChilds[i], strNew).toString();
			}
		}
		return retStr;
	}
	
	/**
	 * 把在strMonther 中出现的strOlds替换为strNews
	 * @param strMonther 原串 
	 * @param strOlds 查找串数组
	 * @param strNew 新串
	 * @param isIgnoreCase 是否忽略大小写
	 * @remark strChilds和strNews要一一对应
	 */
	public static String replaceAllInStrArray(String strMonther,String strOlds[],String strNews[],boolean isIgnoreCase){
		StringBuffer retStr;
		int spos,epos;
		List<Integer> list;
		int index;
		
		//strChilds和strNews长度必须相同
		if( strOlds!=null && strNews!=null && strOlds.length==strNews.length ){
			retStr = new StringBuffer();
			spos = epos = 0;
			while(epos>=0){
				list = findInStrArray(spos, strMonther, strOlds, isIgnoreCase);
				epos = list.get(0);
			    index = list.get(1);
			    if(epos>=0){
			    	retStr.append(strMonther.substring(spos, epos)).append(strNews[index]);
			    	spos = epos+strOlds[index].length();
			    }else{
			    	retStr.append(strMonther.substring(spos));
			    }
			}
			return retStr.toString();
		}else
			return strMonther;
	}
	
	 /**
     * 剥离最末级字符串 例如a.b.c 返回a.b
     * @param str 需要处理str
     * @param separator 级间分隔符
     * @return
     */
    public static String peelOffLastLevelString(String str,String separator){
    	if(str == null )
    		return null;
    	if(str.length()==0)
    		return str;
    	int pos;
    	pos = str.lastIndexOf(separator);
    	if(pos>=0){
    		return str.substring(0,pos);
    	}else
    		return str;
    }
	/**
	 * 校验交易名称是否合法性
	 * @param businessname 交易名称
	 * @return 合法返回true;否则返回false
	 */
	public static boolean validateBusinessName(String name){
		if(isEmpty(name)){
			return false;
		}
		for(int i=0;i<name.length();i++){
			if(!isLetter(name.charAt(i)) && !isNumber(name.charAt(i)) && name.charAt(i)!='_')
				return false;
		}
		return true;
	}
    /**
     * 忽略大小写查找
     * 
     * @param strMonther
     *            母串
     * @param value
     *            字符串
     * @param startpos
     *            开始
     * @return int 返回查找位置
     */
    public static int findStrIgnoreCase(String strMonther, String value, int startpos) {
    	return strMonther.toLowerCase().indexOf(value.toLowerCase(), startpos);
    }
    /**
	 * 异常转换为字符串
	 * 
	 * @param e
	 * @return
	 */
	public static String exceptionToString(Throwable e) {
		if (e != null) {
			PrintStream stream;
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			stream = new PrintStream(out);
			e.printStackTrace(stream);
			return new String(out.toByteArray());
		} else {
			return "";
		}

	}    
}
